/*
* PureMVC Logger v1.0
* Copyright (c) 2009 We Are Cloud.
* Author: Yannick Chaze
*
* Based on PureMVC code
* See http://puremvc.org for more informations
*
* Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0.
*
* PureMVC MultiCore - Copyright(c) 2006-08 Futurescale, Inc., Some rights reserved.
* Your reuse is governed by the Creative Commons Attribution 3.0 United States License
*/

package com.wearecloud.puremvclogger.core
{
	import com.wearecloud.logs.ApplicationLogger;
	import com.wearecloud.puremvclogger.Logger;
	import com.wearecloud.puremvclogger.patterns.observer.ObserverLogger;
	
	import org.puremvc.as3.multicore.core.View;
	import org.puremvc.as3.multicore.interfaces.IMediator;
	import org.puremvc.as3.multicore.interfaces.INotification;
	import org.puremvc.as3.multicore.interfaces.IView;

	/**
	 * The ViewLogger class extends the PureMVC singleton class and
	 * intercepts the notifcations to log informations about them
	 * 
	 * @see org.puremvc.as3.multicore.core.View
	 * @see org.puremvc.as3.multicore.interfaces.IView
	 */
	
	public class ViewLogger extends View implements IView
	{
		/**
		 * @inheritDoc
		 */
		public function ViewLogger ( key:String )
		{
			super( key );
		}
		
		/**
		 * @inheritDoc
		 */
		override public function notifyObservers(notification:INotification):void
		{
			if( observerMap[ notification.getName() ] != null ) {
				
				var observers_ref:Array = observerMap[ notification.getName() ] as Array;

   				var observers:Array = new Array(); 
   				var observer:ObserverLogger;
				
				for (var i:Number = 0; i < observers_ref.length; i++) { 
					observer = observers_ref[ i ] as ObserverLogger;
					observers.push( observer );
				}
				
				for (i = 0; i < observers.length; i++) {
					observer = observers[ i ] as ObserverLogger;
					// Two types of notified object so we grab the notify context to know and then log
					if (observer.getNotifyContext() is ControllerLogger)
						Logger.log( "Command execution: " + (ControllerLogger.getInstance( multitonKey ) as ControllerLogger).getCommandName(notification.getName()) + " for notification: " + notification.getName());
					else
						Logger.log( "Mediator'" + (observer.getNotifyContext() as IMediator).getMediatorName() + "'  handle notification: " + notification.getName());
					observer.notifyObserver( notification );
				}
			}
		}
		
		/**
		 * @inheritDoc
		 */
		override public function removeObserver( notificationName:String, notifyContext:Object ):void
		{
			var observers:Array = observerMap[ notificationName ] as Array;

			for ( var i:int=0; i<observers.length; i++ ) 
			{
				if ( ObserverLogger(observers[i]).compareNotifyContext( notifyContext ) == true ) {
					observers.splice(i,1);
					break;
				}
			}

			if ( observers.length == 0 ) {
				delete observerMap[ notificationName ];		
			}
		} 
		
		/**
		 * @inheritDoc
		 */
		override public function registerMediator( mediator:IMediator ) : void
		{
			mediator.initializeNotifier( multitonKey );
			
			mediatorMap[ mediator.getMediatorName() ] = mediator;
			
			var interests:Array = mediator.listNotificationInterests();

			if ( interests.length > 0 ) 
			{
				var observer:ObserverLogger = new ObserverLogger( mediator.handleNotification, mediator );

				for ( var i:Number=0;  i<interests.length; i++ ) {
					registerObserver( interests[i],  observer );
				}			
			}
			
			mediator.onRegister();
		}
		
		/**
		 * @inheritDoc
		 */
		public static function getInstance( key:String ) : IView 
		{
			if ( instanceMap[ key ] == null ) instanceMap[ key ] = new ViewLogger( key );
			return instanceMap[ key ];
		}
		
		/**
		 * @inheritDoc
		 */
		public static function removeView( key:String ):void
		{
			delete instanceMap[ key ];
		}
	}
}